package cre.tomcat.ch10.core;

import org.apache.catalina.Container;
import org.apache.catalina.Realm;
import org.apache.catalina.realm.GenericPrincipal;

import java.beans.PropertyChangeListener;
import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author penglai
 * @Date 2017/1/29.
 */
public class SimpleRealm implements Realm {

    private Container container;
    private List<User> users = new ArrayList<User>();

    public SimpleRealm() {
        createUserData();
    }

    private void createUserData() {
        User user1 = new User("ken", "ken");
        user1.addRole("manager");
        user1.addRole("programmer");

        User user2 = new User("cindy","cindy");
        user2.addRole("programmer");

        users.add(user1);
        users.add(user2);
    }

    public Container getContainer() {
        return container;
    }

    public void setContainer(Container container) {
        this.container = container;
    }

    public String getInfo() {
        return "A simple realm";
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {

    }

    public Principal authenticate(String username, String credentials) {
        System.out.println("SimpleRealm.authenticate()");
        if (username == null || credentials == null) {
            return null;
        }
        User user = gainUser(username, credentials);
        if (user == null) {
            return null;
        }
        return new GenericPrincipal(this, user.getName(), user.getPassword(), user.getRoles());
    }

    private User gainUser(String username, String credentials) {
        for (User user : users) {
            if (user.getName().equals(username) && user.getPassword().equals(credentials)) {
                return user;
            }
        }
        return null;
    }

    public Principal authenticate(String username, byte[] credentials) {
        return null;
    }

    public Principal authenticate(String username, String digest, String nonce, String nc, String cnonce, String qop, String realm, String md5a2) {
        return null;
    }

    public Principal authenticate(X509Certificate[] certs) {
        return null;
    }

    public boolean hasRole(Principal principal, String role) {
        if (principal instanceof GenericPrincipal) {
            GenericPrincipal genericPrincipal = (GenericPrincipal) principal;
            if (genericPrincipal.getRealm() == this && role != null) {
                return genericPrincipal.hasRole(role);
            }
        }
        return false;
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {

    }

    class User{
        private String name;
        private String password;

        private List<String> roles = new ArrayList<String>();

        public User(String name, String password) {
            this.name = name;
            this.password = password;
        }

        public void addRole(String role) {
            roles.add(role);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public List<String> getRoles() {
            return roles;
        }

        public void setRoles(List<String> roles) {
            this.roles = roles;
        }
    }
}
